package com.pureland.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pureland.common.entity.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @projectName: pureland_cloud
 * @className: com.pureland.security.ResourceAuthExceptionEntryPoint
 * @description: 客户端异常处理,可以根据AuthenticationException 不同细化异常处理
 * @author: tong.li
 * @createTime: 2020/11/17 17:50
 * @version: v1.0
 * @copyright: 版权所有 李彤 © 2020
 */
@Slf4j
@Configuration
@AllArgsConstructor
public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint {

    /**
     * 这块构造器注入
     */
    private final ObjectMapper objectMapper;


    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        R result = R.fail("错误");
        result.setSuccessful(false);
        if (authException != null) {
            String localizedMessage = authException.getLocalizedMessage();
            log.error("[访问受限] - [{}]", localizedMessage);
            if (authException.getCause() instanceof InvalidTokenException) {
                InvalidTokenException invalidTokenException = (InvalidTokenException) authException.getCause();
                int httpErrorCode = invalidTokenException.getHttpErrorCode();
                result.setMessageId(httpErrorCode);
                result.setMessage("Token无效");
            } else if (authException instanceof InsufficientAuthenticationException) {
                int httpErrorCode = HttpStatus.UNAUTHORIZED.value();
                result.setMessageId(httpErrorCode);
                result.setMessage("未认证的用户");
            } else if (authException instanceof BadCredentialsException) {
                int httpErrorCode = HttpStatus.UNAUTHORIZED.value();
                result.setMessageId(httpErrorCode);
                result.setMessage("错误的信任");
            }
        } else {
            result.setMessageId(HttpStatus.UNAUTHORIZED.value());
            result.setMessage(HttpStatus.UNAUTHORIZED.name());
        }
        log.error("[客户端异常]", authException);
        PrintWriter printWriter = response.getWriter();
        printWriter.append(objectMapper.writeValueAsString(result));
    }
}
